// new的时间传session和local，判断是否启用
// 存类型，Object格式转换，时间戳，可以设置过期时间，存列表
// object格式转换，是否重置时间戳，检查时间戳
// 删除单个
// 删除全部
// 开启监听
// 关闭监听
// import Local from './lib/local'
// import Session from './lib/session'
// 应当增加命名空间
// 增加是否加密
// 通用过期时间
import Memory from './lib/memory'
import Store from './lib/store'
import { optionType, unifyOption } from './lib/type'
// 初始化的时候可以是一个对象，也可是是一个字符串
export default function cache(option: optionType | unifyOption = 'local') {
  let type: optionType = 'local'
  // 初始化默认命名空间，无失效时间，不加密
  let unifyOption: unifyOption = {
    namespace: 'cache-tools-',
    failureTime: -1,
    encryption: false,
    secretKey: '3.1415926',
  }
  if (typeof option === 'string') {
    type = option
  }
  if (typeof option === 'object') {
    type = option.type || 'local'
    option.namespace && (unifyOption.namespace = option.namespace)
    option.failureTime && (unifyOption.failureTime = option.failureTime)
    option.encryption && (unifyOption.encryption = option.encryption)
    option.secretKey && (unifyOption.secretKey = option.secretKey)
  }
  unifyOption.type = type
  if (!['local', 'session', 'memory'].includes(type)) {
    throw new Error('不支持该格式')
  }
  if (type == 'local') {
    if (!checkStorageAvailable('localStorage')) {
      throw new Error('localStorage未启用')
    }
    return new Store(window.localStorage, unifyOption)
  }
  if (type == 'session') {
    if (!checkStorageAvailable('sessionStorage')) {
      throw new Error('sessionStorage未启用')
    }
    return new Store(window.sessionStorage, unifyOption)
  }
  if (type == 'memory') {
    return new Store(new Memory() as Storage, unifyOption)
  }
}
// 验证是否可用
function checkStorageAvailable(name: string): boolean {
  let storage = (window as any)[name]
  if (typeof storage !== 'undefined') {
    try {
      storage.setItem('feature_test', 'yes')
      if (storage.getItem('feature_test') === 'yes') {
        storage.removeItem('feature_test')
        return true
      } else {
        return false
      }
    } catch (e) {
      return false
    }
  } else {
    return false
  }
}
